package com.yc.testupload.consumer;

import com.rabbitmq.client.*;
import com.yc.testupload.controller.DocumentsServlet;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.yc.testupload.util.RabbitMQConfig;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;

/**
 * 微信公众号发布任务消息消费者
 * 负责从消息队列获取任务并执行发布操作
 */
public class WechatPublishConsumer {
    private static final Logger logger = LogManager.getLogger(WechatPublishConsumer.class);
    private final String queueName;
    private final DocumentsServlet documentsServlet;
    
    public WechatPublishConsumer(DocumentsServlet documentsServlet) {
        this.queueName = RabbitMQConfig.WECHAT_PUBLISH_QUEUE;
        this.documentsServlet = documentsServlet;
    }
    
    /**
     * 启动消费者，开始监听队列
     */
    public void start() {
        try {
            // 获取RabbitMQ连接
            Connection connection = RabbitMQConfig.getConnection();
            Channel channel = connection.createChannel();
            
            // 声明队列（持久化）
            boolean durable = true;
            channel.queueDeclare(queueName, durable, false, false, null);
            
            // 设置每次只处理一个消息
            channel.basicQos(1);
            
            logger.info("开始监听发布任务队列: {}", queueName);
            
            // 创建消费者
            DeliverCallback deliverCallback = (consumerTag, delivery) -> {
                String message = new String(delivery.getBody(), "UTF-8");
                
                try {
                    // 处理发布任务
                    processPublishTask(message);
                    
                    // 确认消息处理成功
                    channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
                } catch (Exception e) {
                    logger.error("处理发布任务失败: {}", e.getMessage(), e);
                    // 日志记录错误，但仍然确认消息，避免消息重复处理
                    logger.error("任务处理失败: {}", e.getMessage(), e);
                    channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
                }
            };
            
            // 注册消费者，autoAck设置为false，手动确认
            channel.basicConsume(queueName, false, deliverCallback, consumerTag -> { });
            
        } catch (IOException | TimeoutException e) {
            logger.error("启动消费者失败: {}", e.getMessage(), e);
            throw new RuntimeException("启动消费者失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 处理发布任务
     */
    private void processPublishTask(String message) throws Exception {
        JSONObject taskJson = new JSONObject(message);
        String taskId = taskJson.getString("taskId");
        String taskType = taskJson.optString("taskType");
        
        logger.info("开始处理发布任务，任务ID: {}, 任务类型: {}", taskId, taskType);
        
        // 记录任务开始处理
        logger.info("任务处理中，任务ID: {}", taskId);
        
        try {
            Map<String, Object> result;
            
            // 根据任务类型执行不同的发布操作
            if ("MULTIPLE_DOCS_MULTIPLE_ACCOUNTS".equals(taskType)) {
                JSONArray documentsArray = taskJson.getJSONArray("documents");
                JSONArray accountIdsArray = taskJson.getJSONArray("accountIds");
                
                List<String> accountIds = new ArrayList<>();
                for (int i = 0; i < accountIdsArray.length(); i++) {
                    // 处理可能是整数的情况，使用toString()而非getString()
                    Object accountIdObj = accountIdsArray.get(i);
                    accountIds.add(accountIdObj.toString());
                }
                
                // 调用发布方法
                result = documentsServlet.batchPublishToMultipleWechatAccounts(null, documentsArray, accountIds);
            } else if ("SINGLE_DOC_MULTIPLE_ACCOUNTS".equals(taskType)) {
                int documentId = taskJson.getInt("documentId");
                JSONArray accountIdsArray = taskJson.getJSONArray("accountIds");
                
                List<String> accountIds = new ArrayList<>();
                for (int i = 0; i < accountIdsArray.length(); i++) {
                    // 处理可能是整数的情况，使用toString()而非getString()
                    Object accountIdObj = accountIdsArray.get(i);
                    accountIds.add(accountIdObj.toString());
                }
                
                // 创建文档数组
                JSONArray documentsArray = new JSONArray();
                JSONObject docObj = new JSONObject();
                docObj.put("id", documentId);
                docObj.put("title", taskJson.optString("documentTitle", ""));
                documentsArray.put(docObj);
                
                // 调用发布方法
                result = documentsServlet.batchPublishToMultipleWechatAccounts(null, documentsArray, accountIds);
            } else if ("SINGLE_DOC_SINGLE_ACCOUNT".equals(taskType)) {
                int documentId = taskJson.getInt("documentId");
                // 处理可能是整数的情况
                Object accountIdObj = taskJson.get("accountId");
                String accountId = accountIdObj.toString();
                
                // 调用单个文档发布方法
                result = documentsServlet.publishToWechatWithDetails(null, documentId, accountId);
                
                // 适配结果格式
                Map<String, Object> adaptedResult = new HashMap<>();
                Map<String, Object> accountResult = new HashMap<>();
                accountResult.put("successCount", (Boolean)result.get("success") ? 1 : 0);
                accountResult.put("failCount", (Boolean)result.get("success") ? 0 : 1);
                accountResult.put("details", new ArrayList<>());
                accountResult.put("message", result.get("message"));
                
                Map<String, Object> accountResults = new HashMap<>();
                accountResults.put(accountId, accountResult);
                
                adaptedResult.put("accountResults", accountResults);
                adaptedResult.put("totalSuccessCount", (Boolean)result.get("success") ? 1 : 0);
                adaptedResult.put("totalFailCount", (Boolean)result.get("success") ? 0 : 1);
                
                result = adaptedResult;
            } else {
                throw new IllegalArgumentException("未知的任务类型: " + taskType);
            }
            
            // 记录任务完成
            
            logger.info("发布任务处理完成，任务ID: {}, 成功数量: {}, 失败数量: {}", 
                    taskId, result.get("totalSuccessCount"), result.get("totalFailCount"));
            
        } catch (Exception e) {
            logger.error("处理发布任务时发生异常: {}", e.getMessage(), e);
            throw e;
        }
    }
    

}